package com.erau.droidsatframework;

import java.util.HashMap;
import java.util.Iterator;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.graphics.*;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;

import com.erau.droidsatframework.core.*;
import com.erau.droidsatframework.core.CoreService.CoreBinder;
import com.erau.droidsatframework.phidget.PhidgetService.PhidgetBinder;

public class DroidSatActivity extends Activity {
    
	
	private UsbManager usbManager;
	private UsbDevice  phidget;
	private UsbInterface phidgetInt;
	public UsbEndpoint phidgetEndPoint;
	private UsbDeviceConnection phidgetConnection;
	
	private PendingIntent phigetPermissionIntent;
	
	private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
	
	private boolean phidgetConnected = false;
	private boolean connectionActive = false;
	private boolean manModeActive = false;
	private boolean servicesStarted = false;
	private boolean algoStarted = false;
	
	private int cLEFT = 500;
	private int cRIGHT = -500;
	private int cSTOP = 0;//
	
	private byte[] LEFT = {(byte)0x00, (byte)0x81, (byte)0x03, (byte)0xFF, 00, 00, 00, 00}; // See wiki for the source of these values
	private byte[] RIGHT = {(byte)0x00, (byte)0x7F, (byte)0x03, (byte) 0xFF, 00, 00, 00, 00};
	private byte[] STOP = {(byte)0x00, (byte)0x00, (byte)0x03, (byte) 0xFF, 00, 00, 00, 00};
	
	
	
	CoreService coreB;					//Local handle of the CoreService Instance for binding
	private Intent activity2CoreIntent;
	private MediaPlayer lulcatz;
	
	
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        lulcatz = MediaPlayer.create(this, R.raw.rd);//
        
       
        
        
        //Start of Stephen's UI
        setContentView(R.layout.main);

        final Button Start_Svc = (Button) findViewById(R.id.start_svc);
        Start_Svc.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click for Start Service Button
	            	if(servicesStarted == false){
	            	
	            	startSvc();
	            	Toast.makeText(DroidSatActivity.this, "Services Started", 2000).show();
            	}
            }
        });
        
        final Button Start_Alg = (Button) findViewById(R.id.start_alg);
        Start_Alg.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if(servicesStarted == true && algoStarted == false){
                	//algSrt();
                	coreB.startAlgorithm();
                	algoStarted = true;
	            	// Perform action on click for Start Algorithm Button
	            	Toast.makeText(DroidSatActivity.this, "Algorithm Started", 2000).show();
                }
            }
        });
        
        final Button Stop_Alg = (Button) findViewById(R.id.stop_alg);
        Stop_Alg.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click for Stop Algorithm Button
            	coreB.stopAlgorthim();
            	algoStarted = false;
            	Toast.makeText(DroidSatActivity.this, "Algorithm Stopped", 2000).show();
            }
        });
        
        final Button Stop_Svc = (Button) findViewById(R.id.stop_svc);
        Stop_Svc.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click for Stop Service Button
            	stopSvc();
            }
        });
        
        final Button Usb_init = (Button) findViewById(R.id.usb_init);
        Usb_init.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click for USB Initialization Button
            	lulcatz.start();
            	
            	Toast.makeText(DroidSatActivity.this, "ERROR!!!: ID10T", 2000).show();
            }
        });
        
        final Button Man_Mde = (Button) findViewById(R.id.man_mde);
        Man_Mde.setOnClickListener(new View.OnClickListener() {
        	int latch=0;
            public void onClick(View v) {
                
            	
            	if (latch==0) {
            		latch=1;
            		
            		if(servicesStarted){
            			if(algoStarted){
            				
            			}
            		}
            		
            		// Perform action on click for Manual Mode Button
                	manModeInit();
                	manModeActive = true;
                	Toast.makeText(DroidSatActivity.this, "Manual Mode Activated", 2000).show();
                    final Button Left = (Button) findViewById(R.id.left);
                    Left.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                            if(connectionActive){
	                        	// Perform action on click for Left Button while Manual Mode Activated
                            	command(cLEFT);
	                        	Toast.makeText(DroidSatActivity.this, "Left", 2000).show();
                            }
                            else {
                            	Toast.makeText(DroidSatActivity.this, "Please Wait", 2000).show();
                            }
                        }
                    });
                    
                    final Button Right = (Button) findViewById(R.id.right);
                    Right.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                        	if(connectionActive){
	                            // Perform action on click for Right Button while Manual Mode Activated
                        		command(cRIGHT);
	                        	Toast.makeText(DroidSatActivity.this, "Right", 2000).show();
	                       	}
                        	else {
                        		Toast.makeText(DroidSatActivity.this, "Please Wait", 2000).show();
                        	}
                        }
                    });
                    
                    final Button Stop = (Button) findViewById(R.id.stop);
                    Stop.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                        	if(connectionActive){
	                            // Perform action on click for Stop Button while Manual Mode Activated
                        		command(cSTOP);
                        		//lol
	                        	Toast.makeText(DroidSatActivity.this, "Stop", 2000).show();
                        	}
                        	else{
                        		Toast.makeText(DroidSatActivity.this, "Please Wait", 2000).show();
                        	}
                        }
                    });
                    
                    
            	}
            	else {
            		latch=0;
                	Toast.makeText(DroidSatActivity.this, "Manual Mode Deactivated", 2000).show();
                	manModeActive = false;
                	manModeStop();
                	
                    final Button Left = (Button) findViewById(R.id.left);
                    Left.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                            // Perform action on click for Stop Service Button
                        	Toast.makeText(DroidSatActivity.this, "Manual Mode Not Active", 2000).show();
                        }
                    });
                    
                    final Button Right = (Button) findViewById(R.id.right);
                    Right.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                            // Perform action on click for Stop Service Button
                        	Toast.makeText(DroidSatActivity.this, "Manual Mode Not Active", 2000).show();
                        }
                    });
                    
                    final Button Stop = (Button) findViewById(R.id.stop);
                    Stop.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                            // Perform action on click for Stop Service Button
                        	Toast.makeText(DroidSatActivity.this, "Manual Mode Not Active", 2000).show();
                        }
                    });
                    
            	}

            }
        });
        //END OF STEPHENS UI
        
    }
    
    @Override
    public void onStart() {
    	super.onStart();
    	
    }
    
    @Override
    public void onDestroy() {
    	
    	/*
    	if(servicesStarted){
    		stopSvc();
    	}
    	else if (manModeActive){
    		manModeStop();//
    	}*/
    }
    
    private void manModeInit(){
    	//Establish the intent filter and reciever for the permissions stuff...
		phigetPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
		IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
		registerReceiver(phidgetPermissionReceiver, filter);
		
		//Establish the manager
		usbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
		
		//Find the phidget board out of the sea of devices!
		HashMap<String, UsbDevice> foundDevices = usbManager.getDeviceList();
		Iterator<UsbDevice> iterator = foundDevices.values().iterator();
		while(iterator.hasNext()){
			//We are assuming that the phidget board is the only thing that is connected... not exactly
			//good practice but... it is what it is...
			phidget = iterator.next();
			if(phidget != null){
				phidgetConnected = true;
			}
		}
		
		//As long as we found the phidget proceed...
		if(phidgetConnected){
			phidgetInt = phidget.getInterface(0);
			
			phidgetEndPoint = phidgetInt.getEndpoint(0);
			
			//Now we check if we have permission to communicate with the phidget board...
			if(usbManager.hasPermission(phidget)){
				afterPermissionGranted();
			}
			else{
				usbManager.requestPermission(phidget, phigetPermissionIntent);
			}
		}
	}
	
	
    private void afterPermissionGranted(){
		phidgetConnection = usbManager.openDevice(phidget);
		if(phidgetConnection != null){
			if(phidgetConnection.claimInterface(phidgetInt, true)){
			connectionActive = true;
			}
		}
	}
    
    private final BroadcastReceiver phidgetPermissionReceiver = new BroadcastReceiver(){

		@Override
		public void onReceive(Context arg0, Intent arg1) {
			String action = arg1.getAction();
			if(ACTION_USB_PERMISSION.equals(action)){
				synchronized (this) {
					if(arg1.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)){
						afterPermissionGranted();
					}
					else{
						//log no permission
					}
				}
			}
		}	
	};// permission receiver
   
	private void command(int requestedCommand){
		byte[] result = Convert(requestedCommand, 100, 0);
		
			phidgetConnection.controlTransfer(USB_CONSTANTS.TYPE_HID, 0x9, USB_CONSTANTS.USB_2p0, 0,result , result.length, 0);
		
	}
	
	private void startSvc(){
		activity2CoreIntent = new Intent(this, CoreService.class);  //Intent to bind to core
		//startService(activity2CoreIntent);
		bindService(activity2CoreIntent, bindConnection, Context.BIND_AUTO_CREATE ); //Bind
		servicesStarted = true;
		
	}//
	
	private void stopSvc(){
		if(servicesStarted){
    		if(algoStarted){
    			coreB.stopAlgorthim();
    		}
    		//stopService(activity2CoreIntent);
    		coreB.stopRequest();
    		unbindService(bindConnection);
    		servicesStarted = false;
    		Toast.makeText(DroidSatActivity.this, "Services Stopped", 2000).show();
    	}
	}
	
	private void manModeStop() {
		command(cSTOP);
    	phidgetConnection.releaseInterface(phidgetInt);
    	phidgetConnection.close();
	}
	
	private ServiceConnection bindConnection = new ServiceConnection() {

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
		
				CoreBinder coreBinder = (CoreBinder) service; //cast the call back service into the core binder
				coreB = coreBinder.getService();	//bring in the active instance of the core service
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			//dont care... well ok... maybe we do but not at this moment...
		}
	};
	
	public static byte[] Convert(int velocity, int acceleration, int motor) {
		//Velocity Value between -1000 and 1000
		//Acceleration Value between 1 and 100
		//Motor Value is either 0 or 1
		float newVelocity;
		float calcVelocity;
		int phidgetVelocity; 
		String hexVelocity;
		float lastVelocity=0;
		
		float calcAccel;
		int phidgetAccel;
		String hexAccel="0";
		float lastAccel=1;
		
		String hexMotor;
		
		int hex1, hex2, hex3, hex4;
		String hexstring;
		int length;
		
		newVelocity=(float) (velocity/10.0);
		
		if (velocity<0 && velocity >=-1000) {
			calcVelocity=(float) (1.269607*(Math.round(newVelocity))+255.975152);
		}
		else if (velocity<=1000 && velocity >=0) {
			calcVelocity=(float) (1.269621*(Math.round(newVelocity)) + 0.023879);
		}
		else {
			calcVelocity= lastVelocity;
		}
		
		lastVelocity=calcVelocity;
		
		if (motor!=0 && motor!=1) {
			//Default motor to port 0
			motor=0;
		}
		
		hexMotor=Integer.toHexString(motor);
		hex1=Integer.parseInt("0".concat(hexMotor),16);
		
		if (acceleration>=1 && acceleration <=100) {
			calcAccel=(float) (acceleration*10.23);
		}
		else {
			calcAccel=lastAccel;
		}
		
		lastAccel=calcAccel;
		
		phidgetAccel=Math.round(calcAccel);
		
		phidgetVelocity=Math.round(calcVelocity);

		hexVelocity=Integer.toHexString(phidgetVelocity).toUpperCase();
		hexstring=Integer.toHexString(phidgetAccel).toUpperCase();
		
		hex2=Integer.parseInt(hexVelocity,16);
		
		length=hexstring.length();
		
		switch (length) {
		case 1: hexAccel="000".concat(hexstring);  break;
		case 2: hexAccel="00".concat(hexstring);  break;
		case 3: hexAccel="0".concat(hexstring);  break;
		}
		
		hex3=Integer.parseInt(hexAccel.substring(0,2),16);
		hex4=Integer.parseInt(hexAccel.substring(2,4),16);
		
		byte[] phidgetValue={(byte) hex1, (byte) hex2, (byte) hex3, (byte) hex4, 00, 00, 00, 00};
		
		return phidgetValue;  
	} 
    
}